package org.noear.solon.extend.sessionstate.local;

import org.noear.solon.Utils;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.SessionStateDefault;


/**
 * 它会是个单例，不能有上下文数据
 * */
public class LocalSessionState extends SessionStateDefault {
    private static int _expiry = 60 * 60 * 2;
    private static String _domain = null;
    private static ScheduledStore _store;

    static {
        if (XServerProp.session_timeout > 0) {
            _expiry = XServerProp.session_timeout;
        }

        if (XServerProp.session_state_domain != null) {
            _domain = XServerProp.session_state_domain;
        }

        _store = new ScheduledStore(_expiry);
    }

    private Context ctx;

    protected LocalSessionState(Context ctx) {
        this.ctx = ctx;
    }

    //
    // cookies control

    public String cookieGet(String key) {
        return ctx.cookie(key);
    }

    public  void   cookieSet(String key, String val) {

        if (XServerProp.session_state_domain_auto) {
            if (_domain != null) {
                if(ctx.uri().getHost().indexOf(_domain) < 0){ //非安全域
                    ctx.cookieSet(key, val, null, _expiry);
                    return;
                }
            }
        }

        ctx.cookieSet(key, val, _domain, _expiry);
    }



    //
    // session control
    //

    @Override
    public String sessionId() {
        String _sessionId = ctx.attr("sessionId", null);

        if (_sessionId == null) {
            _sessionId = sessionId_get();
            ctx.attrSet("sessionId", _sessionId);
        }

        return _sessionId;
    }

    private String sessionId_get() {
        String skey = cookieGet(SESSIONID_KEY);
        String smd5 = cookieGet(SESSIONID_MD5());

        if (Utils.isEmpty(skey) == false && Utils.isEmpty(smd5) == false) {
            if (Utils.md5(skey + SESSIONID_salt).equals(smd5)) {
                return skey;
            }
        }

        skey = Utils.guid();
        cookieSet(SESSIONID_KEY, skey);
        cookieSet(SESSIONID_MD5(), Utils.md5(skey + SESSIONID_salt));
        return skey;
    }

    @Override
    public Object sessionGet(String key) {
        return _store.get(sessionId(), key);
    }

    @Override
    public void sessionSet(String key, Object val) {
        _store.put(sessionId(), key, val);
    }

    @Override
    public void sessionClear() {
        _store.remove(sessionId());
    }

    @Override
    public void sessionRefresh() {
        String skey = cookieGet(SESSIONID_KEY);

        if (Utils.isEmpty(skey) == false) {
            cookieSet(SESSIONID_KEY, skey);
            cookieSet(SESSIONID_MD5(), Utils.md5(skey + SESSIONID_salt));

            _store.delay(sessionId());
        }
    }



    @Override
    public boolean replaceable() {
        return false;
    }
}
